#include "../test_helpers.h"
#include "MessageHeader.h"
#include <spdlog/spdlog.h>
#include <gtest/gtest.h>

using namespace MessageFramework;
using namespace MessageFramework::Test;

class MessageHeaderTest : public ::testing::Test {
protected:
    void SetUp() override {
        spdlog::set_level(spdlog::level::debug);
    }
};

// ==================== 基础功能测试 ====================

TEST_F(MessageHeaderTest, DefaultConstructor) {
    MessageHeader header;

    // 验证默认值
    EXPECT_STREQ(header.version, "1.0");
    EXPECT_STREQ(header.contentType, "JSON");
    EXPECT_EQ(header.priority, 5);
    EXPECT_FALSE(header.encrypted);
    EXPECT_EQ(header.timestamp, 0);
}

TEST_F(MessageHeaderTest, GenerateMessageId) {
    std::string id1 = MessageHeader::generateMessageId();
    std::string id2 = MessageHeader::generateMessageId();

    // MessageID应该唯一
    EXPECT_NE(id1, id2);
    EXPECT_GT(id1.length(), 0);
    EXPECT_GT(id2.length(), 0);
}

TEST_F(MessageHeaderTest, GenerateTraceId) {
    std::string trace1 = MessageHeader::generateTraceId();
    std::string trace2 = MessageHeader::generateTraceId();

    // TraceID应该唯一
    EXPECT_NE(trace1, trace2);
    EXPECT_GT(trace1.length(), 0);
    EXPECT_GT(trace2.length(), 0);
}

// ==================== 序列化/反序列化测试 ====================

TEST_F(MessageHeaderTest, SerializeDeserialize) {
    // 创建测试Header
    MessageHeader original = TestHelpers::createTestHeader("TestType", "TestPublisher");
    std::strcpy(original.consumerId, "TestConsumer");
    std::strcpy(original.replyStream, "reply_stream");
    original.priority = 7;

    // 序列化
    std::string serialized = original.serialize();
    EXPECT_GT(serialized.length(), 0);

    // 反序列化
    MessageHeader deserialized = MessageHeader::deserialize(serialized);

    // 验证字段
    EXPECT_STREQ(original.messageId, deserialized.messageId);
    EXPECT_STREQ(original.messageType, deserialized.messageType);
    EXPECT_STREQ(original.version, deserialized.version);
    EXPECT_STREQ(original.publisherId, deserialized.publisherId);
    EXPECT_STREQ(original.consumerId, deserialized.consumerId);
    EXPECT_STREQ(original.targetStream, deserialized.targetStream);
    EXPECT_STREQ(original.replyStream, deserialized.replyStream);
    EXPECT_EQ(original.timestamp, deserialized.timestamp);
    EXPECT_EQ(original.priority, deserialized.priority);
    EXPECT_STREQ(original.contentType, deserialized.contentType);
}

// ==================== Redis字段转换测试 ====================

TEST_F(MessageHeaderTest, ToRedisFields) {
    MessageHeader header = TestHelpers::createTestHeader();
    std::strcpy(header.consumerId, "TestConsumer");
    header.priority = 8;
    header.encrypted = true;

    auto fields = header.toRedisFields();

    // 验证关键字段存在
    EXPECT_EQ(fields.count("messageId"), 1);
    EXPECT_EQ(fields.count("messageType"), 1);
    EXPECT_EQ(fields.count("publisherId"), 1);
    EXPECT_EQ(fields.count("consumerId"), 1);
    EXPECT_EQ(fields.count("priority"), 1);
    EXPECT_EQ(fields.count("encrypted"), 1);

    // 验证值正确
    EXPECT_STREQ(fields["messageId"].c_str(), header.messageId);
    EXPECT_STREQ(fields["messageType"].c_str(), header.messageType);
    EXPECT_STREQ(fields["publisherId"].c_str(), header.publisherId);
    EXPECT_STREQ(fields["consumerId"].c_str(), header.consumerId);
    EXPECT_EQ(std::stoi(fields["priority"]), 8);
    EXPECT_EQ(fields["encrypted"], "1");
}

TEST_F(MessageHeaderTest, FromRedisFields) {
    // 创建Redis字段
    std::map<std::string, std::string> fields;
    fields["messageId"] = "test-msg-123";
    fields["messageType"] = "TestMessage";
    fields["version"] = "1.0";
    fields["publisherId"] = "Publisher1";
    fields["consumerId"] = "Consumer1";
    fields["targetStream"] = "test_stream";
    fields["replyStream"] = "reply_stream";
    fields["timestamp"] = "123456789";
    fields["expiresAt"] = "987654321";
    fields["signature"] = "abcd1234";
    fields["encrypted"] = "1";
    fields["encryptionAlgo"] = "AES-256-GCM";
    fields["traceId"] = "trace-123";
    fields["parentId"] = "parent-456";
    fields["priority"] = "9";
    fields["contentLength"] = "1024";
    fields["contentType"] = "JSON";

    // 从Redis字段构建Header
    MessageHeader header = MessageHeader::fromRedisFields(fields);

    // 验证所有字段
    EXPECT_STREQ(header.messageId, "test-msg-123");
    EXPECT_STREQ(header.messageType, "TestMessage");
    EXPECT_STREQ(header.version, "1.0");
    EXPECT_STREQ(header.publisherId, "Publisher1");
    EXPECT_STREQ(header.consumerId, "Consumer1");
    EXPECT_STREQ(header.targetStream, "test_stream");
    EXPECT_STREQ(header.replyStream, "reply_stream");
    EXPECT_EQ(header.timestamp, 123456789);
    EXPECT_EQ(header.expiresAt, 987654321);
    EXPECT_STREQ(header.signature, "abcd1234");
    EXPECT_TRUE(header.encrypted);
    EXPECT_STREQ(header.encryptionAlgo, "AES-256-GCM");
    EXPECT_STREQ(header.traceId, "trace-123");
    EXPECT_STREQ(header.parentId, "parent-456");
    EXPECT_EQ(header.priority, 9);
    EXPECT_EQ(header.contentLength, 1024);
    EXPECT_STREQ(header.contentType, "JSON");
}

// ==================== 验证测试 ====================

TEST_F(MessageHeaderTest, ValidateSuccess) {
    MessageHeader header = TestHelpers::createTestHeader();

    EXPECT_TRUE(header.validate());
}

TEST_F(MessageHeaderTest, ValidateFailure_EmptyMessageId) {
    MessageHeader header = TestHelpers::createTestHeader();
    header.messageId[0] = '\0';  // 清空messageId

    EXPECT_FALSE(header.validate());
}

TEST_F(MessageHeaderTest, ValidateFailure_EmptyMessageType) {
    MessageHeader header = TestHelpers::createTestHeader();
    header.messageType[0] = '\0';

    EXPECT_FALSE(header.validate());
}

TEST_F(MessageHeaderTest, ValidateFailure_EmptyPublisherId) {
    MessageHeader header = TestHelpers::createTestHeader();
    header.publisherId[0] = '\0';

    EXPECT_FALSE(header.validate());
}

TEST_F(MessageHeaderTest, ValidateFailure_EmptyTargetStream) {
    MessageHeader header = TestHelpers::createTestHeader();
    header.targetStream[0] = '\0';

    EXPECT_FALSE(header.validate());
}

TEST_F(MessageHeaderTest, ValidateFailure_InvalidPriority) {
    MessageHeader header = TestHelpers::createTestHeader();

    header.priority = -1;
    EXPECT_FALSE(header.validate());

    header.priority = 10;
    EXPECT_FALSE(header.validate());

    header.priority = 0;
    EXPECT_TRUE(header.validate());

    header.priority = 9;
    EXPECT_TRUE(header.validate());
}

TEST_F(MessageHeaderTest, ValidateFailure_ZeroTimestamp) {
    MessageHeader header = TestHelpers::createTestHeader();
    header.timestamp = 0;

    EXPECT_FALSE(header.validate());
}

// ==================== 过期检查测试 ====================

TEST_F(MessageHeaderTest, IsExpired_NoExpiration) {
    MessageHeader header = TestHelpers::createTestHeader();
    header.expiresAt = 0;  // 不过期

    EXPECT_FALSE(header.isExpired());
}

TEST_F(MessageHeaderTest, IsExpired_FutureExpiration) {
    MessageHeader header = TestHelpers::createTestHeader();

    // 设置10秒后过期
    auto now = std::chrono::high_resolution_clock::now();
    auto future = now + std::chrono::seconds(10);
    header.expiresAt = std::chrono::duration_cast<std::chrono::nanoseconds>(
        future.time_since_epoch()).count();

    EXPECT_FALSE(header.isExpired());
}

TEST_F(MessageHeaderTest, IsExpired_PastExpiration) {
    MessageHeader header = TestHelpers::createTestHeader();

    // 设置10秒前过期
    auto now = std::chrono::high_resolution_clock::now();
    auto past = now - std::chrono::seconds(10);
    header.expiresAt = std::chrono::duration_cast<std::chrono::nanoseconds>(
        past.time_since_epoch()).count();

    EXPECT_TRUE(header.isExpired());
}

// ==================== 边界条件测试 ====================

TEST_F(MessageHeaderTest, MaxLengthFields) {
    MessageHeader header;

    // 填充最大长度字符串
    std::string maxString(63, 'A');  // 63个字符（留1个给\0）

    std::strncpy(header.messageId, maxString.c_str(), sizeof(header.messageId) - 1);
    std::strncpy(header.publisherId, (maxString.substr(0, 31)).c_str(),
                 sizeof(header.publisherId) - 1);

    // 验证字符串正确截断
    EXPECT_EQ(std::strlen(header.messageId), 63);
    EXPECT_EQ(std::strlen(header.publisherId), 31);
}

int main(int argc, char** argv) {
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}
